为了符合restful风格,最近在做项目时,除了GET和POST请求,还决定使用PUT和DELETE请求,但是在使用springMVC进行这个两个类型的请求时

     $.ajax({
        url:‘***’,
        type:‘put’,
        data:{}
      })

发现controller接收的自定义实体类形参的各个属性都是null,原因是浏览器本身只支持get和post方法,因此需要使用_method这个隐藏字段来告知spring这是一个put请求。所以type是不能变动的,否则浏览器不支持。 为此,spring3.0添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求,该过滤器是HiddenHttpMethodFilter。

    public class HiddenHttpMethodFilter extends OncePerRequestFilte{

        /** Default method parameter: <code>_method</code> */
        public static final String DEFAULT_METHOD_PARAM = "_method";

        private String methodParam = DEFAULT_METHOD_PARAM;


        /**
         * Set the parameter name to look for HTTP methods.
         * @see #DEFAULT_METHOD_PARAM
         */
        public void setMethodParam(String methodParam) {
            Assert.hasText(methodParam, "'methodParam' must not be empty");
            this.methodParam = methodParam;
        }

        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
        throws ServletException, IOException {

        String paramValue = request.getParameter(this.methodParam);
        if ("POST".equals(request.getMethod()) && StringUtils.hasLength(paramValue)) {
        String method = paramValue.toUpperCase(Locale.ENGLISH);
        HttpServletRequest wrapper = new HttpMethodRequestWrapper(request, method);
        filterChain.doFilter(wrapper, response);
    }
    else {
        filterChain.doFilter(request, response);
    }
}

查看这个filter的源码你会发现这个过滤器的原理其实就是将http请求中的_method属性值在doFilterInternal方法中转化为标准的http方法。
需要注意的是,doFilterInternal方法中的if条件判断http请求是否POST类型并且请求参数中是否含有_method字段,也就是说方法只对method为post的请求进行过滤,所哟请求必须如下设置:

   $.ajax({
        url:‘***’,
        type:‘post’,
        data:{
                 _method:put,
              }
      }) 

同时HiddenHttpMethodFilter必须作用于dispatch前,所以需要在web.xml中配置一个filter

    <filter>  
    <filter-name>HiddenHttpMethodFilter</filter-name>  
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
</filter>  

<filter-mapping>  
    <filter-name>HiddenHttpMethodFilter</filter-name>  
    <servlet-name>ROOT</servlet-name>  
</filter-mapping>

这样,springmvc就能处理put和delete请求了。
完。


zclau
359 声望12 粉丝

Java后端,爱好Java、C、Unix,喜欢钻研基础技术、基础架构